package com.itheima.appserver.service;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.dubbo.config.annotation.Reference;
import com.itheima.appserver.interceptor.UserThreadLocal;
import com.itheima.commons.constants.Constants;
import com.itheima.commons.model.domain.*;
import com.itheima.commons.model.mongo.RecommendUser;
import com.itheima.commons.model.mongo.UserLike;
import com.itheima.commons.model.mongo.Visitors;
import com.itheima.commons.model.vo.*;
import com.itheima.dubbo.interfaces.*;
import org.apache.commons.lang3.StringUtils;
import org.bson.types.ObjectId;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * 个人中心业务类
 */

@Service
public class MyCenterService {

    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    @Reference
    private UserLikeApi userLikeApi;

    @Autowired
    private VisitorsService visitorsService;

    @Reference
    private RecommendUserApi recommendUserApi;

    @Autowired
    private IMService imService;

    @Reference
    private QuestionApi questionApi;

    @Autowired
    UserInfoService userInfoService;

    @Autowired
    UserService userService;

    @Reference
    private BlackListApi blackListApi;

    @Reference
    private SettingsApi settingsApi;


    /**
     * 喜欢数/粉丝数/互相喜欢数
     *
     * @return
     */
    public CountsVo queryCounts() {
        CountsVo countsVo = new CountsVo();
        // 互相喜欢数量
        Long mutualCount = userLikeApi.queryMutualLikeCount(UserThreadLocal.getUserId());
        countsVo.setEachLoveCount(mutualCount);


        // 喜欢数
        // 先查询Redis  如果有就直接设置 如果没有就查询MongoDB
        Long size = redisTemplate.opsForSet().size(Constants.USER_LIKE_KEY + UserThreadLocal.getUserId());
        countsVo.setLoveCount(size);
        if (size == 0) {
            // 查询MongoDB重新赋值
            Long count = userLikeApi.queryLikeCount(UserThreadLocal.getUserId());
            countsVo.setLoveCount(count);
        }

        // 粉丝数
        Long fanCount = userLikeApi.queryFanCount(UserThreadLocal.getUserId());
        countsVo.setFanCount(fanCount);

        return countsVo;
    }

    /**
     * 查询 喜欢 / 粉丝 / 互相喜欢 / 访客列表
     *
     * @param type
     * @param page
     * @param pageSize
     * @param nickname
     * @return
     */
    public PageResult queryLikeList(Integer type, Integer page, Integer pageSize, String nickname) {
        // 先判断是哪个请求
        // 1 互相关注 2 我喜欢 3 粉丝 4 谁看过我
        // 来访者/喜欢/粉丝/互相喜欢人的id集合
        List<Long> userIds = new ArrayList<>();
        // 喜欢/粉丝/互相喜欢人的列表
        List<UserLike> userLikes = new ArrayList<>();
        // 来访者列表
        List<Visitors> visitors = new ArrayList<>();
        switch (type) {
            case 1: {
                // 互相喜欢
                userLikes = userLikeApi.queryMutualLikeList(UserThreadLocal.getUserId(), page, pageSize);
                userIds = CollUtil.getFieldValues(userLikes, "userId", Long.class);
                break;
            }
            case 2: {
                // 喜欢
                userLikes = userLikeApi.queryLikeList(UserThreadLocal.getUserId(), page, pageSize);
                userIds = CollUtil.getFieldValues(userLikes, "likeUserId", Long.class);
                break;
            }
            case 3: {
                // 粉丝
                userLikes = userLikeApi.queryFanList(UserThreadLocal.getUserId(), page, pageSize);
                userIds = CollUtil.getFieldValues(userLikes, "userId", Long.class);
                break;
            }
            case 4: {
                // 来访者列表
                visitors = visitorsService.queryVisitorByPages(UserThreadLocal.getUserId(), page, pageSize);
                userIds = CollUtil.getFieldValues(visitors, "visitorUserId", Long.class);

                // 记录这次的查询时间
                redisTemplate.opsForValue().set(Constants.VISITORS_USER_KEY + UserThreadLocal.getUserId(), Convert.toStr(System.currentTimeMillis()));
                break;
            }
        }

        // 统一处理  VO对象
        if (CollUtil.isEmpty(userIds)){
            return new PageResult();
        }
        Map<Long, UserInfo> userInfoMap = userInfoService.findUserInfoListByUserIds(null, userIds);

        List<UserLikeListVo> userLikeListVos = new ArrayList<>();
        for (UserInfo userInfo : userInfoMap.values()) {
            UserLikeListVo userLikeListVo = new UserLikeListVo();
            userLikeListVo.setAge(userInfo.getAge());
            userLikeListVo.setAvatar(userInfo.getLogo());
            userLikeListVo.setCity(userInfo.getCity());
            userLikeListVo.setEducation(userInfo.getEdu());
            userLikeListVo.setGender(userInfo.getSex() == 1 ? "man" : "woman");
            userLikeListVo.setId(userInfo.getUserId());
            userLikeListVo.setMarriage(StringUtils.equals(userInfo.getMarriage(), "已婚") ? 1 : 0);
            userLikeListVo.setNickname(userInfo.getNickName());
            //是否喜欢  userLikeApi中的isLike开放出来
            userLikeListVo.setAlreadyLove(userLikeApi.isLike(UserThreadLocal.getUserId(), userInfo.getUserId()));
            userLikeListVo.setMatchRate(90);
            // 查询推荐的缘分值
            if (type == 4) {
                RecommendUser recommendUser = recommendUserApi.queryScoreByUserId(UserThreadLocal.getUserId(), userInfo.getUserId());
                if (ObjectUtil.isNotEmpty(recommendUser)) {
                    userLikeListVo.setMatchRate(Convert.toInt(recommendUser.getScore()));
                }
            }
            userLikeListVos.add(userLikeListVo);
        }

        return new PageResult(page, pageSize, 0L, userLikeListVos);
    }

    /**
     * 取消喜欢
     *
     * @param userId
     */
    public void disLike(Long userId) {
        // 先判断俩人是否互相喜欢
        if (userLikeApi.isMutualLike(UserThreadLocal.getUserId(), userId)) {
            // 互相喜欢
            // 解除好友关系
            // 先删除好友表中的两条记录
            // 给环信发送请求
            imService.remoeContactUser(userId);
        }
        // 删除MongoDB中的数据
        userLikeApi.notLikeUser(UserThreadLocal.getUserId(), userId);
        // 删除Redis中的数据
        redisTemplate.opsForSet().remove(Constants.USER_LIKE_KEY + UserThreadLocal.getUserId(), userId.toString());
    }


    /**
     * 喜欢粉丝
     *
     * @param userId
     */
    public void likeFan(Long userId) {
        // 添加到MongoDB
        UserLike userLike = new UserLike();
        userLike.setId(new ObjectId());
        userLike.setUserId(UserThreadLocal.getUserId());
        userLike.setLikeUserId(userId);
        userLike.setCreated(System.currentTimeMillis());
        userLikeApi.likeUser(userLike);

        // 添加到Redis
        redisTemplate.opsForSet().add(Constants.USER_LIKE_KEY + UserThreadLocal.getUserId(), userId.toString());

        // 绑定两人的好友关系
        imService.contactUser(userId);
    }

    /**
     * 更新用户个人信息
     *
     * @param userInfoVo
     */
    public void updateUserInfo(UserInfoVo userInfoVo) {
        UserInfo userInfo = new UserInfo();
        userInfo.setNickName(userInfoVo.getNickname());
        userInfo.setUserId(UserThreadLocal.getUserId());
        userInfo.setAge(Integer.valueOf(userInfoVo.getAge()));
        userInfo.setSex(userInfoVo.getGender());
        userInfo.setBirthday(userInfoVo.getBirthday());
        userInfo.setCity(userInfoVo.getCity());
        userInfo.setEdu(userInfoVo.getEducation());
        userInfo.setIncome(StrUtil.replaceIgnoreCase(userInfoVo.getIncome(), "K", ""));
        userInfo.setIndustry(userInfoVo.getProfession());
        userInfo.setMarriage(userInfoVo.getMarriage() == 1 ? "已婚" : "未婚");
        userInfoService.updateUserInfoByUserId(userInfo);
    }

    /**
     * 个人主页设置查询
     *
     * @return
     */
    public SettingsVo querySettings() {
        SettingsVo settingsVo = new SettingsVo();
        //设置用户的基本信息
        settingsVo.setId(UserThreadLocal.getUserId());
        settingsVo.setPhone(UserThreadLocal.getUserMobile());

        //查询用户的配置数据
        Settings settings = settingsApi.querySettings(UserThreadLocal.getUserId());
        if (ObjectUtil.isNotEmpty(settings)) {
            settingsVo.setGonggaoNotification(settings.getGonggaoNotification());
            settingsVo.setLikeNotification(settings.getLikeNotification());
            settingsVo.setPinglunNotification(settings.getPinglunNotification());
        }

        //查询陌生人问题
        Question question = questionApi.findQuestionByUserId(UserThreadLocal.getUserId());
        settingsVo.setStrangerQuestion(ObjectUtil.isEmpty(question) ? "你的爱好是什么?" : question.getTxt());

        return settingsVo;
    }

    /**
     * 设置陌生人问题
     *
     * @param content
     */
    public void saveQuestions(String content) {
        questionApi.saveQuestions(UserThreadLocal.getUserId(), content);
    }

    /**
     * 查询黑名单
     *
     * @param page
     * @param pagesize
     * @return
     */
    public PageResult queryBlacklist(Integer page, Integer pagesize) {
        // 查询黑名单数据
        List<BlackList> blackList = blackListApi.queryBlacklist(UserThreadLocal.getUserId(), page, pagesize);
        // 如果没有黑名单返回一个空集合
        if (CollUtil.isEmpty(blackList)) {
            return new PageResult();
        }

        // 提取黑名单用户的id
        List<Long> userIds = CollUtil.getFieldValues(blackList, "blackUserId", Long.class);
        if (CollUtil.isEmpty(userIds)){
            return new PageResult();
        }
        // 查询黑名单用户id对应的用户详情
        Map<Long, UserInfo> userInfoMap = userInfoService.findUserInfoListByUserIds(null, userIds);

        List<BlackListVo> blackListVos = new ArrayList<>();
        for (UserInfo userInfo : userInfoMap.values()) {
            BlackListVo blackListVo = new BlackListVo();
            blackListVo.setAge(userInfo.getAge());
            blackListVo.setAvatar(userInfo.getLogo());
            blackListVo.setGender(userInfo.getSex() == 1 ? "man" : "woman");
            blackListVo.setId(userInfo.getUserId());
            blackListVo.setNickname(userInfo.getNickName());

            blackListVos.add(blackListVo);
        }

        return new PageResult(page, pagesize, 0L, blackListVos);
    }

    /**
     * 删除黑名单
     *
     * @param userId
     */
    public void delBlacklist(Long userId) {
        blackListApi.delBlacklist(UserThreadLocal.getUserId(), userId);
    }

    /**
     * 更新通知
     *
     * @param likeNotification
     * @param pinglunNotification
     * @param gonggaoNotification
     */
    public void updateNotification(Boolean likeNotification, Boolean pinglunNotification, Boolean gonggaoNotification) {
        settingsApi.updateNotification(UserThreadLocal.getUserId(), likeNotification, pinglunNotification, gonggaoNotification);
    }

    /**
     * 更新头像
     *
     * @param file
     */
    public void saveUserLogo(MultipartFile file) {
        userInfoService.loginReginfoHead(file);
    }

    /**
     * 更改手机号码--发送短信验证码
     */
    public void sendVerificationCode() {
        userService.sendLoginMsg(UserThreadLocal.getUserMobile());
    }

    /**
     * 更改手机号码--校验短信验证码
     *
     * @param code
     * @return
     */
    public Boolean checkVerificationCode(String code) {
        Map map = userService.loginVerification(UserThreadLocal.getUserMobile(), code);
        return ObjectUtil.isNotEmpty(map);
    }

    /**
     * 更改手机号码--保持新手机号码
     *
     * @param newPhone
     */
    public void updatePhone(String newPhone) {
        userService.updatePhone(UserThreadLocal.getUserId(), newPhone);
    }

    public UserInfoVo queryUserInfoByUserId(Long userId) {
        UserInfo userInfo = userInfoService.findUserInfoByUserId(ObjectUtil.isEmpty(userId) ? UserThreadLocal.getUserId() : userId);

        UserInfoVo userInfoVo = new UserInfoVo();
        // 用户的ID
        userInfoVo.setId(userInfo.getUserId());
        userInfoVo.setAvatar(userInfo.getLogo());
        userInfoVo.setNickname(userInfo.getNickName());
        userInfoVo.setBirthday(userInfo.getBirthday());
        userInfoVo.setAge(userInfo.getAge().toString());
        userInfoVo.setGender(userInfo.getSex() == 1 ? "man" : "woman");
        userInfoVo.setCity(userInfo.getCity());
        userInfoVo.setEducation(userInfo.getEdu());
        userInfoVo.setIncome(userInfo.getIncome());
        userInfoVo.setProfession(userInfo.getIndustry());
        userInfoVo.setMarriage(userInfo.getMarriage() == "已婚" ? 1 : 0);

        return userInfoVo;
    }
}
